﻿module DWFx

let BIN_GLUE_SET = [|'0'; '1'|]
let DNA_GLUE_SET = [|'A'; 'T'; 'C'; 'G'|]


let unknown = '?'
let DetWords n l k1 k4 (glues : char array) =
    let M = Array2D.init l n (fun i j -> unknown)
    for i = 0 to l - 1 do
        for j = 0 to n - 1 do
            // Finds the glue with the largest expectation
            M.[i, j] <- 
                [| 0 .. glues.Length - 1|]
                |> Array.maxBy (fun x ->
                    let mutable test = M
                    test.[i, j] <- glues.[x]
                    ExpCount.ExpCount M k1 k4 glues.Length)
                |> Array.get glues

            //if (ExpCount.ExpCount M k1 k4 glues.Length) = 0.0 then
            //    ExpCount.IssueError "No possible word set will fit the constraints"
    M

let outputDW n l k1 k4 =
    let M = DetWords n l k1 k4 BIN_GLUE_SET
    let createTable =
        let p = M.GetLength(0)
        let q = M.GetLength(1)
        let mutable tableString = ""
        for i = 0 to (p-1) do
            tableString <- tableString + "<tr><td>Word " + string (i+1) + ": &nbsp; </td>"
            for j = 0 to (q-1) do
                if M.[i,j] = '0' then
                    tableString <- tableString + "<td style=\"background-color: black; padding: .3em; color: white;\">" + "0" + "</td>"
                elif M.[i,j] = '1' then
                    tableString <- tableString + "<td style=\"background-color: silver; padding: .3em; color: black;\">" + "1" + "</td>"
            done
            tableString <- tableString + "</tr><tr><td>&nbsp;</td></tr>"
        done
        tableString
            
    sprintf "%s" createTable

(*
// alphabet size of A, C, T, G (max prob out of A, C, T, G)
// ASYNC THIS
let DetWordsDNA n l k1 k4 =
        
    let mutable M = Array2D.init n l (fun i j -> unknown)
    let mutable MA = Array2D.init n l (fun i j -> unknown)
    let mutable MC = Array2D.init n l (fun i j -> unknown)
    let mutable MT = Array2D.init n l (fun i j -> unknown)
    let mutable MG = Array2D.init n l (fun i j -> unknown)
        
       
    for i = 0 to M.GetLength(0) - 1 do
        for j = 0 to M.GetLength(1) - 1 do
            
            MA.[i, j] <- 'A'
            MC.[i, j] <- 'C'
            MT.[i, j] <- 'T'
            MG.[i, j] <- 'G'

            let EA = (ExpCount.ExpCount MA k1 k4 4)
            let EC = (ExpCount.ExpCount MC k1 k4 4)
            let ET = (ExpCount.ExpCount MT k1 k4 4)
            let EG = (ExpCount.ExpCount MG k1 k4 4)

            // use the max probability here
            if ((EA >= EC) && (EA >= ET) && (EA >= EG)) then
                M.[i, j] <- 'A'
                MA.[i, j] <- 'A'
                MC.[i, j] <- 'A'
                MT.[i, j] <- 'A'
                MG.[i, j] <- 'A'
            elif ((ET >= EA) && (ET >= EC) && (ET >= EG)) then
                M.[i, j] <- 'T'
                MA.[i, j] <- 'T'
                MC.[i, j] <- 'T'
                MT.[i, j] <- 'T'
                MG.[i, j] <- 'T'
            elif ((EC >= EA) && (EC >= ET) && (EC >= EG)) then
                M.[i, j] <- 'C'
                MA.[i, j] <- 'C'
                MC.[i, j] <- 'C'
                MT.[i, j] <- 'C'
                MG.[i, j] <- 'C'
            elif ((EG >= EA) && (EG >= ET) && (EG >= EC)) then
                M.[i, j] <- 'G'
                MA.[i, j] <- 'G'
                MC.[i, j] <- 'G'
                MT.[i, j] <- 'G'
                MG.[i, j] <- 'G'
            else
                M.[i, j] <- 'E'
    M*)

let outputDWDNA n l k1 k4 =
    // !! PROBLEM --> must switch n and l so it is l n or something.
    let M = DetWords n l k1 k4 DNA_GLUE_SET
    let bob = M.GetLength(1)

    let Mbox = Array.init bob (fun i -> utils.getColumn i M)
    printfn "M: %A" M
    printfn "mbox: %A" Mbox
    tester.testBasicHammingConstraint Mbox k1
    tester.testShiftingHammingConstraint Mbox k4

    let createTable =
        let p = Mbox.GetLength(0)
        let q = Mbox.[0].GetLength(0)
        let mutable tableString = ""
        for i = 0 to (p-1) do
            tableString <- tableString + "<tr><td>Word " + string (i+1) + ": &nbsp; 3'</td>"
            for j = 0 to (q-1) do
                if Mbox.[i].[j] = 'A' then
                    tableString <- tableString + "<td style=\"background-color: #5050ff; padding: .3em; color: black;\">" + "A" + "</td>"
                elif Mbox.[i].[j] = 'C' then
                    tableString <- tableString + "<td style=\"background-color: #e00000; padding: .3em; color: black;\">" + "C" + "</td>"
                elif Mbox.[i].[j] = 'T' then
                    tableString <- tableString + "<td style=\"background-color: #e6e600; padding: .3em; color: black;\">" + "T" + "</td>"
                elif Mbox.[i].[j] = 'G' then
                    tableString <- tableString + "<td style=\"background-color: #00c000; padding: .3em; color: black;\">" + "G" + "</td>"
                //tableString <- tableString + "<td>" + final_M.[i,j].ToString() + "</td>"
            done
            tableString <- tableString + "<td>5'</td></tr><tr><td>&nbsp;</td></tr>"
        done
        tableString
            
    sprintf "%s" createTable